/*
  ******************************************************************************
  * @file    uart_demo.c
  * @author  FreqChip Firmware Team
  * @version V1.0.0
  * @date    2021
  * @brief   UART module Demo.
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2021 FreqChip.
  * All rights reserved.
  ******************************************************************************
*/
#include "uart_demo.h"
#include "driver_gpio.h"
#include "driver_pmu.h"
#include "driver_dma.h"
#include "driver_uart_ex.h"
#include "co_printf.h"
#include "co_log.h"

uint8_t Checkbuf[256];

GPIO_InitTypeDef    GPIO_Handle;
UART_HandleTypeDef  Uart1_handle;
DMA_HandleTypeDef   DMA_Chan0;
DMA_HandleTypeDef   DMA_Chan1;
/************************************************************************************
 * @fn      uart_demo
 *
 * @brief   uart demo
 *
 * @param   fe_Demo: demo select. 

 */

void uart_demo(enum_uart_Demo_t uart_Demo)
{  
    __SYSTEM_UART1_CLK_ENABLE();

    /* init GPIO Alternate Function */
    GPIO_Handle.Pin       = GPIO_PIN_2|GPIO_PIN_3;
    GPIO_Handle.Mode      = GPIO_MODE_AF_PP;
    GPIO_Handle.Pull      = GPIO_PULLUP;
    GPIO_Handle.Alternate = GPIO_FUNCTION_5;
    gpio_init(GPIO_A, &GPIO_Handle);

    /* init uart1 */   
    Uart1_handle.UARTx = Uart1;
    Uart1_handle.Init.BaudRate   = 115200;
    Uart1_handle.Init.DataLength = UART_DATA_LENGTH_8BIT;
    Uart1_handle.Init.StopBits   = UART_STOPBITS_1;
    Uart1_handle.Init.Parity     = UART_PARITY_NONE;
    Uart1_handle.Init.FIFO_Mode  = UART_FIFO_ENABLE;
    
    uart_init_ex(&Uart1_handle);
    
    switch(uart_Demo)
    {
        /* uart transmit and receive*/
        case UART_TRANSMIT_RECEIVE:
        {
            co_printf("Uart1 transmit and receive start\r\n");
            
            while(1)
            {
                uart_receive(&Uart1_handle, Checkbuf, 1);            
                uart_transmit(&Uart1_handle, Checkbuf, 1);                
            }
        }
        
        /* uart transmit and receive use interrupt*/        
        case UART_TRANSMIT_RECEIVE_IT:
        {
            co_printf("Uart1 transmit_IT and receive_IT start\r\n");
            
            NVIC_EnableIRQ(UART1_IRQn);
            NVIC_SetPriority(UART1_IRQn, 0);
            
            uart_receive_IT(&Uart1_handle, Checkbuf, 256);
            while(Uart1_handle.b_RxBusy);
            
            uart_transmit_IT(&Uart1_handle, Checkbuf, 256);
            while(Uart1_handle.b_TxBusy);
            
            co_printf("Uart1 transmit_IT and receive_IT end\r\n");
            
            while(1);        
        }
        
        /* uart transmit and receive use dma*/ 
        case UART_TRANSMIT_RECEIVE_DMA:
        {
            co_printf("Uart1 transmit_dma and receive_dma start\r\n");

            __DMA_REQ_ID_UART1_TX(1);
            __DMA_REQ_ID_UART1_RX(2);
            DMA_Chan0.Channel               = DMA_Channel0;
            DMA_Chan0.Init.Data_Flow        = DMA_M2P_DMAC;
            DMA_Chan0.Init.Request_ID       = 1;
            DMA_Chan0.Init.Source_Inc       = DMA_ADDR_INC_INC;
            DMA_Chan0.Init.Desination_Inc   = DMA_ADDR_INC_NO_CHANGE;
            DMA_Chan0.Init.Source_Width     = DMA_TRANSFER_WIDTH_8;
            DMA_Chan0.Init.Desination_Width = DMA_TRANSFER_WIDTH_8;
            dma_init(&DMA_Chan0);
            

            DMA_Chan1.Channel               = DMA_Channel1;
            DMA_Chan1.Init.Data_Flow        = DMA_P2M_DMAC;
            DMA_Chan1.Init.Request_ID       = 2;
            DMA_Chan1.Init.Source_Inc       = DMA_ADDR_INC_NO_CHANGE;
            DMA_Chan1.Init.Desination_Inc   = DMA_ADDR_INC_INC;
            DMA_Chan1.Init.Source_Width     = DMA_TRANSFER_WIDTH_8;
            DMA_Chan1.Init.Desination_Width = DMA_TRANSFER_WIDTH_8;
            dma_init(&DMA_Chan1);
            
            uart_transmit_DMA(&Uart1_handle);
            uart_receive_DMA(&Uart1_handle);

            dma_start(&DMA_Chan1, (uint32_t)&Uart1_handle.UARTx->DATA_DLL.DATA, (uint32_t)Checkbuf, 256, DMA_BURST_LEN_1, DMA_BURST_LEN_1);
            while(!dma_get_tfr_Status(DMA_Channel1));
            dma_clear_tfr_Status(DMA_Channel1);
            
            dma_start(&DMA_Chan0, (uint32_t)Checkbuf, (uint32_t)&Uart1_handle.UARTx->DATA_DLL.DATA, 256, DMA_BURST_LEN_1, DMA_BURST_LEN_1);     
            while(!dma_get_tfr_Status(DMA_Channel0));
            dma_clear_tfr_Status(DMA_Channel0);
    
            co_printf("Uart1 transmit_dma and receive_dma end\r\n");
            
            while(1);   
        }  
    }
}

void uart1_isr(void)
{
    uart_IRQHandler(&Uart1_handle);
}
